---
title: "VSftpd笔记"
categories:
- linux
tags:
---

<div id="content">
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orgadd54b3">Intro</a></li>
<li><a href="#section">0</a></li>
<li><a href="#创建存储虚拟用户账号密码的文件">1. 创建存储虚拟用户账号密码的文件</a></li>
<li><a href="#修改vsftpd配置文件">2. 修改vsftpd配置文件</a></li>
<li><a href="#创建pam文件">3. 创建pam文件</a></li>
<li><a href="#创建虚拟用户的主目录">4. 创建虚拟用户的主目录</a></li>
<li><a href="#重启vsftpd">5. 重启vsftpd</a></li>
<li><a href="#troubleshooting">Troubleshooting</a>
<ul>
<li><a href="#orgaf6bcf5">启动报错？</a></li>
<li><a href="#org2fdef4f">连不上？</a></li>
<li><a href="#orge6a8897">连接之后vsftpd: refusing to run with writable root inside chroot()</a></li>
<li><a href="#org780ec1a">文件操作被拒绝？</a></li>
<li><a href="#orgf4a7d41">要使用其他目录作为用户home目录？</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="outline-2" id="outline-container-orgadd54b3">
<h2 id="orgadd54b3">Intro</h2>
<div class="outline-text-2" id="text-orgadd54b3">
<blockquote>
<p>
<a href="https://help.ubuntu.com/community/vsftpd#Virtual%5C_users%5C_with%5C_TLS.2FSSL.2FFTPS%5C_and%5C_a%5C_common%5C_upload%5C_directory%5C_-%5C_Complicated%5C_VSFTPD">https://help.ubuntu.com/community/vsftpd#Virtual\_users\_with\_TLS.2FSSL.2FFTPS\_and\_a\_common\_upload\_directory\_-\_Complicated\_VSFTPD</a>
</p>
</blockquote>
</div>
</div>
<div class="outline-2" id="outline-container-org0614ab1">
<h2 id="section"><a id="org0614ab1"></a>0</h2>
<div class="outline-text-2" id="text-section">
<p>
虚拟用户，即系统中不存在的账户：不存在于/etc/passwd中，没有home目录，无法登陆系统，但是能登陆vsftp。即使存在，也能不适用系统登陆密码去登陆ftp服务器，这样提高了安全性（如果没有配置TLS/SSL/FTPS，则密码是明文传输的，如果使用了系统账户密码登陆则很危险）。
</p>
<p>
宿主用户，因为虚拟用户不存在，所有对虚拟用户对ftp服务器上的文件的读写权限由宿主用户决定。
</p>
<p>
PAM，插入式验证模块，参考
<a href="https://www.ibm.com/developerworks/cn/linux/l-pam/index.html">https://www.ibm.com/developerworks/cn/linux/l-pam/index.html</a>
阅读详细信息。
</p>
</div>
</div>
<div class="outline-2" id="outline-container-org1db9be5">
<h2 id="创建存储虚拟用户账号密码的文件"><a id="org1db9be5"></a>1. 创建存储虚拟用户账号密码的文件</h2>
<div class="outline-text-2" id="text-创建存储虚拟用户账号密码的文件">
<p>
1.1 使用db4格式文件存储账号密码
首先创建一个文本文件，内容为一行账号，一行密码。例如创建两个用户："vivek"，密码"vivekpass"；用户sayali，密码sayalipass:
</p>
<pre class="example">
# mkdir /etc/vsftpd # 创建配置文件的目录，如果没有
# cd /etc/vsftpd
# sudo gedit vusers.txt # 编辑文件，一行账号一行密码

// 下面的内容声明了两个账户：vivek和sayali，偶数行为他们的密码偶数行为他们的密码
vivek
vivekpass
sayali
sayalipass
</pre>
<p>
下一步，创建数据库。将文本转化成数据库。 (需要安装db\_util包):
</p>
<pre class="example">
# db_load -T -t hash -f vusers.txt vsftpd-virtual-user.db # 输出了vsftpd-virtual-user.db文件，即数据库
# chmod 600 vsftpd-virtual-user.db # 更改权限
# rm vusers.txt # 保存了明文密码，所以删了；或者改变读写权限
</pre>
<p>
vsftpd-virtual-user.db为数据库文件, 这里使用了Berkeley DB存储账号密码.
使用db\_dump vsftpd-virtual-user.db 能查看到内容。
</p>
<p>
2.2 htpasswd方式存储账号密码
</p>
<p>
使用文件存储，则使用如下命令，配置pam文件的时候注意更改模块名
</p>
<pre class="example">
$ sudo htpasswd -cd /etc/vsftpd/ftpd.passwd user1
// If you want to add new users afterwards:
$ sudo htpasswd -d /etc/vsftpd/ftpd.passwd user2
// 对应的pam配置中要改成。pam的配置在下面
auth required pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd
account required pam_permit.so
</pre>
</div>
</div>
<div class="outline-2" id="outline-container-orga25bacc">
<h2 id="修改vsftpd配置文件"><a id="orga25bacc"></a>2. 修改vsftpd配置文件</h2>
<div class="outline-text-2" id="text-修改vsftpd配置文件">
<p>
下边列出了启用虚拟用户需要的配置，其他vsftpd服务器的配置参考官方文档
</p>
<pre class="example">
anonymous_enable=NO
local_enable=YES
# Virtual users will use the same privileges as local users.
# It will grant write access to virtual users. Virtual users will use the
# same privileges as anonymous users, which tends to be more restrictive
# (especially in terms of write access).
virtual_use_local_privs=YES
write_enable=YES

# 设置pam，下一步设置pam
pam_service_name=vsftpd.virtual

# 开启虚拟用户
guest_enable=YES

# 通过以下方式指定虚拟用户的宿主
# 例如overlord，overlord是系统存在的真实用户。
# guest_username=overlord 


# Automatically generate a home directory for each virtual user, based on a template.
# For example, if the home directory of the real user specified via guest_username is
# /home/virtual/$USER, and user_sub_token is set to $USER, then when virtual user vivek
# logs in, he will end up (usually chroot()'ed) in the directory /home/virtual/vivek.
# This option also takes affect if local_root contains user_sub_token.
user_sub_token=$USER

# Usually this is mapped to Apache virtual hosting docroot, so that
# Users can upload files
# 配置虚拟用户的home目录，$USER是变量。上面创建了两个用户，则他们的home目录为
# /home/vsftp/vivek /home/vsftp/sayali这两个目录
local_root=/home/vftp/$USER

# Chroot user and lock down to their home dirs
chroot_local_user=YES

# Hide ids from user
hide_ids=YES

# 其他配置...
dirlist_enable=YES  # 允许列出目录
download_enable=YES # 
</pre>
</div>
</div>
<div class="outline-2" id="outline-container-org23675ed">
<h2 id="创建pam文件"><a id="org23675ed"></a>3. 创建pam文件</h2>
<div class="outline-text-2" id="text-创建pam文件">
<p>
pam文件用于用户授权。pam文件中指定了授权模块和账户数据库。
</p>
<pre class="example">
# sudo gedit /etc/pam.d/vsftpd.virtual

// Append (or create with) the following:

#%PAM-1.0
auth       required     pam_userdb.so db=/etc/vsftpd/vsftpd-virtual-user
account    required     pam_userdb.so db=/etc/vsftpd/vsftpd-virtual-user
session    required     pam_loginuid.so
</pre>
</div>
</div>
<div class="outline-2" id="outline-container-org52d7d51">
<h2 id="创建虚拟用户的主目录"><a id="org52d7d51"></a>4. 创建虚拟用户的主目录</h2>
<div class="outline-text-2" id="text-创建虚拟用户的主目录">
<pre class="example">
# mkdir /home/vftp
# mkdir -p /home/vftp/{vivek,sayali}
# chown -R ftp:ftp /home/vftp # 赋予宿主用户读写权限，使虚拟用户能访问
</pre>
</div>
</div>
<div class="outline-2" id="outline-container-org40b5fa8">
<h2 id="重启vsftpd"><a id="org40b5fa8"></a>5. 重启vsftpd</h2>
<div class="outline-text-2" id="text-重启vsftpd">
<pre class="example">
# systemctl stop vsftpd.service
# systemctl start vsftpd.service
</pre>
</div>
</div>
<div class="outline-2" id="outline-container-org02286ab">
<h2 id="troubleshooting"><a id="org02286ab"></a>Troubleshooting</h2>
<div class="outline-text-2" id="text-troubleshooting">
</div>
<div class="outline-3" id="outline-container-orgaf6bcf5">
<h3 id="orgaf6bcf5">启动报错？</h3>
<div class="outline-text-3" id="text-orgaf6bcf5">
<ul class="org-ul">
<li>用=ps aux | grep ftp=查看进程是否存在，如果存在则kill。</li>
<li>找到启动脚本，运行脚本，如果配置文件出错，会有提示。</li>
</ul>
</div>
</div>
<div class="outline-3" id="outline-container-org2fdef4f">
<h3 id="org2fdef4f">连不上？</h3>
<div class="outline-text-3" id="text-org2fdef4f">
<p>
检查防火墙
</p>
</div>
</div>
<div class="outline-3" id="outline-container-orge6a8897">
<h3 id="orge6a8897">连接之后vsftpd: refusing to run with writable root inside chroot()</h3>
<div class="outline-text-3" id="text-orge6a8897">
<p>
从 vsftpd 2.3.5 开始为了避免一个安全漏洞，chroot目录必须不可写。将用户的根目录去掉写权限
</p>
<pre class="example">
# chmod a-w /home/vsftp/vivek/
</pre>
</div>
</div>
<div class="outline-3" id="outline-container-org780ec1a">
<h3 id="org780ec1a">文件操作被拒绝？</h3>
<div class="outline-text-3" id="text-org780ec1a">
<blockquote>
<p>
<a href="https://serverfault.com/questions/522602/vsftpd-vitual-users-selinux">https://serverfault.com/questions/522602/vsftpd-vitual-users-selinux</a>
</p>
</blockquote>
<p>
检查selinux，ftp目录需要设置public_content_rw_t，
</p>
<pre class="example">
chcon -t public_content_rw_t /home/vftp/vivek
#使用=ls -lZ /ftp=查看该目录有没有设置
</pre>
</div>
</div>
<div class="outline-3" id="outline-container-orgf4a7d41">
<h3 id="orgf4a7d41">要使用其他目录作为用户home目录？</h3>
<div class="outline-text-3" id="text-orgf4a7d41">
<blockquote>
<p>
<a href="https://serverfault.com/questions/566145/vsftpd-single-user-with-multiple-directries-centos-6-0">https://serverfault.com/questions/566145/vsftpd-single-user-with-multiple-directries-centos-6-0</a>
</p>
</blockquote>
<p>
使用linux的挂载目录功能（linux &gt; 2.4.0)：
</p>
<pre class="example">
mount --bind /var/www/dev/ /home/vftp/vivek
</pre>
</div>
</div>
</div>
</div>
<div class="status" id="postamble">
<p class="author">Author: gdme1320</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
